﻿using Agile.Infra.Core.Agile;
using Agile.Infra.Repository;
using Agile.Shared.Application.Interceptors;
using Microsoft.Extensions.Caching.Memory;

namespace Agile.Shared.Application.Registrar;

public abstract partial class AbstractApplicationDependencyRegistrar : IDependencyRegistrar
{
    public string Name => "application";
    public abstract Assembly ApplicationLayerAssembly { get; }
    public abstract Assembly ContractsLayerAssembly { get; }
    public abstract Assembly RepositoryOrDomainLayerAssembly { get; }
    //protected SkyApmExtensions SkyApm { get; init; }
    //protected List<AddressNode> RpcAddressInfo { get; init; }
    protected IServiceCollection Services { get; init; }
    protected IConfiguration Configuration { get; init; }
    protected IServiceInfo ServiceInfo { get; init; }
    //protected IConfigurationSection RedisSection { get; init; }
    protected IConfigurationSection CachingSection { get; init; }
    protected IConfigurationSection SqlSugarSection { get; init; }
    protected IConfigurationSection IdYitterSection { get; init; }
    //protected IConfigurationSection WxAppletSection { get; init; }
    //protected IConfigurationSection MongoDbSection { get; init; }
    //protected IConfigurationSection ConsulSection { get; init; }
    //protected IConfigurationSection RabbitMqSection { get; init; }
    protected bool PollyStrategyEnable { get; init; }

    protected AbstractApplicationDependencyRegistrar(IServiceCollection services)
    {
        Services = services ?? throw new ArgumentException("IServiceCollection is null.");
        Configuration = services.GetConfiguration() ?? throw new ArgumentException("Configuration is null.");
        ServiceInfo = services.GetServiceInfo() ?? throw new ArgumentException("ServiceInfo is null.");
        Appsettings.Initialization(Configuration);
        //RedisSection = Configuration.GetSection(NodeConsts.Redis);
        CachingSection = Configuration.GetSection(NodeConsts.Caching);
        //MongoDbSection = Configuration.GetSection(NodeConsts.MongoDb);
        SqlSugarSection = Configuration.GetSection(NodeConsts.SqlSugarSection);
        IdYitterSection = Configuration.GetSection(NodeConsts.IdYitterSection);
        //WxAppletSection = Configuration.GetSection(NodeConsts.WxAppletSection);
        //ConsulSection = Configuration.GetSection(NodeConsts.Consul);
        //RabbitMqSection = Configuration.GetSection(NodeConsts.RabbitMq);
        //SkyApm = Services.AddSkyApmExtensions();
        //RpcAddressInfo = Configuration.GetSection(NodeConsts.RpcAddressInfo).Get<List<AddressNode>>();
        PollyStrategyEnable = Configuration.GetValue("Polly:Enable", false);
    }

    /// <summary>
    /// 注册所有服务
    /// </summary>
    public abstract void AddAgile();

    /// <summary>
    /// 注册Agile.application通用服务
    /// </summary>
    protected virtual void AddApplicaitonDefault()
    {
        Services
            .AddHttpClient()
            .AddScoped<IUnitOfWork, UnitOfWork>()
            .AddMemoryCache()
        .AddORCode()
        //.AddValidatorsFromAssembly(ContractsLayerAssembly, ServiceLifetime.Scoped);
        //.AddAgileInfraAutoMapper(ApplicationLayerAssembly)
        .AddAgileIdGenerater(IdYitterSection)
        .AddWxApplet(Configuration)
        .AddWxPay(Configuration)
        //.AddAgileInfraConsul(ConsulSection)
        //.AddAgileInfraDapper()
        ;

        AddApplicationSharedServices();
        AddAppliactionSerivcesWithInterceptors();
        //AddApplicaitonHostedServices();
        //AddEfCoreContextWithRepositories();
        //AddMongoContextWithRepositries();
        //AddRedisCaching();
        //AddBloomFilters();
    }

    /// <summary>
    /// 注册application.shared层服务
    /// </summary>
    protected void AddApplicationSharedServices()
    {
        Services.AddSingleton(typeof(Lazy<>)); 
        Services.AddScoped<UserContext>();
        Services.AddAgileSqlSugar(SqlSugarSection);
        Services.AddScoped<OperateLogInterceptor>();
        Services.AddScoped<OperateLogAsyncInterceptor>();
        Services.AddScoped<UowInterceptor>();
        Services.AddScoped<UowAsyncInterceptor>();
        //Services.AddSingleton<IBloomFilter, NullBloomFilter>();
        //Services.AddSingleton<BloomFilterFactory>();
        //Services.AddHostedService<CachingHostedService>();
        //Services.AddHostedService<BloomFilterHostedService>();
        //Services.AddHostedService<Channels.ChannelConsumersHostedService>();
        //Services.AddScoped<IMessageTracker, DbMessageTrackerService>();
        //Services.AddScoped<IMessageTracker, RedisMessageTrackerService>();
        //Services.AddScoped<MessageTrackerFactory>();
    }
}